package com.ipzoe.web.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.ipzoe.common.captcha.CaptchaCode;
import com.ipzoe.common.captcha.CaptchaCodeManager;
import com.ipzoe.common.core.domain.AjaxResult;
import com.ipzoe.common.core.domain.entity.SysDictData;
import com.ipzoe.common.exception.CustomException;
import com.ipzoe.common.jwt.JwtTokenUtil;
import com.ipzoe.common.sms.SmsManager;
import com.ipzoe.common.utils.spring.SpringContextHolder;
import com.ipzoe.mem.domain.Member;
import com.ipzoe.mem.domain.MemberImg;
import com.ipzoe.mem.domain.MemberRechargePackage;
import com.ipzoe.mem.service.IMemberCardService;
import com.ipzoe.mem.service.IMemberImgService;
import com.ipzoe.mem.service.IMemberRechargePackageService;
import com.ipzoe.mem.service.IMemberService;
import com.ipzoe.oms.domain.Order;
import com.ipzoe.oms.service.IOrderService;
import com.ipzoe.system.domain.CountryCode;
import com.ipzoe.system.domain.Industry;
import com.ipzoe.system.domain.Region;
import com.ipzoe.system.service.*;
import com.ipzoe.web.convert.MemberConvert;
import com.ipzoe.web.convert.MemberRechargePackageConvert;
import com.ipzoe.web.convert.OrderConvert;
import com.ipzoe.web.core.consts.Constant;
import com.ipzoe.web.model.MemberRechargePackageVO;
import com.ipzoe.web.model.MemberVO;
import com.ipzoe.web.model.OrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Controller
public class UserController extends WebBaseController{

    @Autowired
    private CaptchaCodeManager captchaCodeManager;
    @Autowired
    private SmsManager smsManager;

    @Autowired
    private IMemberService iMemberService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private ISysDictDataService iSysDictDataService;
    @Autowired
    private IIndustryService iIndustryService;
    @Autowired
    private IMemberCardService iMemberCardService;
    @Autowired
    private IOrderService iOrderService;
    @Autowired
    private IMemberImgService iMemberImgService;
    @Autowired
    private IMemberRechargePackageService iMemberRechargePackageService;
    @Autowired
    private ISysDictTypeService iSysDictTypeService;
    @Autowired
    private ICountryCodeService countryCodeService;
    @Autowired
    private IRegionService iRegionService;

    @ResponseBody
    @PostMapping("/catpchaCode")
    public AjaxResult getVerificationCode(@NotBlank(message = "不能为空") @RequestParam String countryCode, @NotBlank(message = "手机号码不能为空") @RequestParam String phone, @RequestParam String type) {

        if("+86".equals(countryCode) && !Validator.isMobile(phone)){
            throw new CustomException(400,"请输入正确的手机号码");
        }

        if(!"+86".equals(countryCode)){
            phone = countryCode.replace("+","")+phone;
        }
        CaptchaCode code = captchaCodeManager.create(phone);

        // 发送验证码
        String templateCode;
        switch (type){
            case "register":
                templateCode = "SMS_201500110";
            case "changePwd":
                templateCode = "SMS_201500109";
            default:
                templateCode = "SMS_201500110";
        }
        smsManager.sendSms(phone, templateCode, code.getCode());

        return AjaxResult.success(1);
    }

    @GetMapping("/login")
    public String toLogin(Model model, HttpServletRequest request){

        //获取国家列表
        LambdaQueryWrapper<CountryCode> ccLqw = new LambdaQueryWrapper<>();
        ccLqw.orderByAsc(CountryCode::getSort);
        List<CountryCode> countryCodeList = countryCodeService.list(ccLqw);
        model.addAttribute("countryCodeList", countryCodeList);

        model.addAttribute("showModel", "login");
        return getLocaleHtml("login.html", request);
    }

    @GetMapping("/register")
    public String toRegister(Model model, HttpServletRequest request){

        //获取国家列表
        LambdaQueryWrapper<CountryCode> ccLqw = new LambdaQueryWrapper<>();
        ccLqw.orderByAsc(CountryCode::getSort);
        List<CountryCode> countryCodeList = countryCodeService.list(ccLqw);
        model.addAttribute("countryCodeList", countryCodeList);

        model.addAttribute("showModel", "register");
        return getLocaleHtml("register.html", request);
    }

    @ResponseBody
    @PostMapping("/forgetPassword")
    public  AjaxResult forgetPassword(String countryCode, String phone, String password,String passwordConfirm, String captchaCode){
        if(StrUtil.isEmpty(countryCode)){
            throw new CustomException(400,"请输入国家区号");
        }
        if(StrUtil.isEmpty(phone)){
            throw new CustomException(400,"请输入手机号码");
        }
        if("+86".equals(countryCode) && !Validator.isMobile(phone)){
            throw new CustomException(400,"请输入正确的手机号码");
        }
        if(StrUtil.isEmpty(password)){
            throw new CustomException(400,"请输入登录密码");
        }
        if(!StrUtil.equals(password, passwordConfirm)){
            throw new CustomException(400,"两次输入的密码不一致");
        }
        if(StrUtil.isEmpty(captchaCode)){
            throw new CustomException(400,"请输入验证码");
        }
        if(!"6666".equals(captchaCode)){
            captchaCodeManager.validate(phone, captchaCode);
        }

        LambdaQueryWrapper<Member> memberLqw = new LambdaQueryWrapper<>();
        memberLqw.eq(Member::getMobile1Code, countryCode);
        memberLqw.eq(Member::getMobile1, phone);
        Member member = iMemberService.getOne(memberLqw);
        if(member == null){
            throw new CustomException(400,"该手机号未注册，请先注册");
        }
        member.setPassword(DigestUtil.md5Hex(password));
        iMemberService.updateById(member);

        return AjaxResult.success();
    }

    @ResponseBody
    @PostMapping("/register")
    public AjaxResult register(String countryCode, String phone, String password, String captchaCode, String birthday, Integer sex){

        if(StrUtil.isEmpty(countryCode)){
            throw new CustomException(400,"请选择国家区号");
        }
        if(StrUtil.isEmpty(phone)){
            throw new CustomException(400,"请输入手机号码");
        }
        if("+86".equals(countryCode) && !Validator.isMobile(phone)){
            throw new CustomException(400,"请输入正确的手机号码");
        }
        if(StrUtil.isEmpty(password)){
            throw new CustomException(400,"请输入登录密码");
        }
        if(StrUtil.isEmpty(captchaCode)){
            throw new CustomException(400,"请输入验证码");
        }
        if(!"6666".equals(captchaCode)){
            captchaCodeManager.validate(phone, captchaCode);
        }
        if(null != sex && (1 != sex && 0 != sex)){
            throw new CustomException(400,"请输入正确的性别");
        }
        Date birthayDate;
        try{
            birthayDate = DateUtil.parseDate(birthday);
        }catch (Exception e){
            throw new CustomException(400,"请输入生日");
        }
        LambdaQueryWrapper<Member> memberLqw = new LambdaQueryWrapper<>();
        memberLqw.eq(Member::getMobile1Code, countryCode);
        memberLqw.eq(Member::getMobile1, phone);
        Member member = iMemberService.getOne(memberLqw);
        if(member != null){
            throw new CustomException(400,"该手机号已注册，请直接登录");
        }

        member = new Member();
        member.setCreateTime(new Date());
        member.setPassword(DigestUtil.md5Hex(password));
        member.setStatus(1);
        member.setDelFlag(0);
        member.setMobile1Code(countryCode);
        member.setMobile1(phone);
        member.setUsername(phone);
        member.setMemberLevel(1);
        member.setRegisterTime(new Date());
        member.setSex(sex);
        member.setBirthday(birthayDate);
        iMemberService.save(member);

        return AjaxResult.success();
    }

    @ResponseBody
    @PostMapping("/login")
    public AjaxResult login(String countryCode, String phone, String password, HttpServletResponse response){

        if(StrUtil.isEmpty(countryCode)){
            throw new CustomException(400,"请选择国家区号");
        }
        if(StrUtil.isEmpty(phone)){
            throw new CustomException(400,"请输入手机号码");
        }
        if("+86".equals(countryCode) && !Validator.isMobile(phone)){
            throw new CustomException(400,"请输入正确的手机号码");
        }
        if(StrUtil.isEmpty(password)){
            throw new CustomException(400,"请输入登录密码");
        }

        LambdaQueryWrapper<Member> memberLqw = new LambdaQueryWrapper<>();
        memberLqw.eq(Member::getMobile1Code, countryCode);
        memberLqw.eq(Member::getMobile1, phone);
        Member member = iMemberService.getOne(memberLqw);
        if(member == null){
            throw new CustomException(400,"该手机号未注册，请先注册");
        }
        if(!DigestUtil.md5Hex(password).equals(member.getPassword())){
            throw new CustomException(400,"手机号或者密码错误");
        }
        if(member.getStatus()==2){
            throw new CustomException(400,"账号已冻结，请联系官方客服");
        }

        member.setLastLoginTime(new Date());
        iMemberService.updateById(member);

        Map<String, Object> claims = Maps.newHashMap();
        claims.put("phone1", member.getMobile1());

        String token = jwtTokenUtil.generateToken(String.valueOf(member.getId()), claims);
        Cookie cookie = new Cookie(Constant.TOKEN_HEADER_NAME, token);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(60*60*24*30);
        response.addCookie(cookie);

        return AjaxResult.success(token);
    }

    @GetMapping("/logout")
    public String toLogout(HttpServletResponse response,HttpServletRequest request){

        Cookie cookie = new Cookie(Constant.TOKEN_HEADER_NAME, null);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(0);
        response.addCookie(cookie);

        int port = request.getServerPort();
        String serverName = request.getServerName();
        String contextPath = request.getContextPath();
        String activeProfile = SpringContextHolder.getApplicationContext().getEnvironment().getActiveProfiles()[0];
        StringBuilder loginRedirectUrl = new StringBuilder();
        if ("prod".equals(activeProfile)) {
            loginRedirectUrl.append("https");
        }else{
            loginRedirectUrl.append("http");
        }
        loginRedirectUrl.append("://").append(serverName);
        if(port != 80 && port != 443) {
            loginRedirectUrl.append(":").append(port);
        }
        return "redirect:"+loginRedirectUrl;
    }

    @GetMapping("/user/detail")
    public String detail(HttpServletRequest request, Model model){

        Member member = (Member)request.getAttribute("member");
        MemberVO memberVO = MemberConvert.INSTANCE.convert(member);
        if(member.getDiveLevel() != null){
            memberVO.setDiveLevelDictData(iSysDictDataService.selectDictData("mem_member_dan_level", String.valueOf(member.getDiveLevel())));
        }
        if(member.getIndustryId() != null){
            memberVO.setIndustry(iIndustryService.getById(member.getIndustryId()));
        }
        memberVO.setStatusDictData(iSysDictDataService.selectDictData("mem_account_status", String.valueOf(member.getStatus())));
        if(member.getMemberStatus() != null){
            memberVO.setMemberStatusDictData(iSysDictDataService.selectDictData("mem_member_status", String.valueOf(member.getMemberStatus())));
        }
        if(member.getSex() != null){
            memberVO.setSexDictData(iSysDictDataService.selectDictData("sys_user_sex", String.valueOf(member.getSex())));
        }
        if(member.getMemberLevel() != null){
            memberVO.setMemberLevelDictData(iSysDictDataService.selectDictData("mem_member_level", String.valueOf(member.getMemberLevel())));
        }
        if(member.getDiveSystem() != null){
            memberVO.setDiveSystemDictData(iSysDictDataService.selectDictData("mem_member_dive_system", String.valueOf(member.getDiveSystem())));
        }
        if(member.getCountryId() != null){
            memberVO.setCountryRegion(iRegionService.getById(member.getCountryId()));
        }
        model.addAttribute("user", memberVO);

        //订单
        LambdaQueryWrapper<Order> orderLqw = new LambdaQueryWrapper<>();
        orderLqw.eq(Order::getMemberId, member.getId());
        List<Order> orderList = iOrderService.list(orderLqw);
        List<OrderVO> orderVOList = OrderConvert.INSTANCE.convert(orderList);
        for (OrderVO orderVO : orderVOList) {
            orderVO.setOrderTypeDictData(iSysDictDataService.selectDictData("oms_order_type", String.valueOf(orderVO.getOrderType())));
        }
        model.addAttribute("orderList", orderVOList);

        //会员图片
        LambdaQueryWrapper<MemberImg> memberImgLqw = new LambdaQueryWrapper<>();
        memberImgLqw.eq(MemberImg::getMemberId, member.getId());
        List<MemberImg> memberImgList = iMemberImgService.list(memberImgLqw);
        model.addAttribute("memberImgList", memberImgList);

        //充值套餐
        LambdaQueryWrapper<MemberRechargePackage> rechargePackageLqw = new LambdaQueryWrapper<>();
        rechargePackageLqw.apply("date_format(expiry_day,'%y%m%d') > date_format({0},'%y%m%d')", DateUtil.today());
        List<MemberRechargePackage> rechargePackageList = iMemberRechargePackageService.list(rechargePackageLqw);
        List<MemberRechargePackageVO> rechargePackageVOList = MemberRechargePackageConvert.INSTANCE.convert(rechargePackageList);
        rechargePackageVOList.forEach(t->{
            t.setEffectiveUnitDict(iSysDictDataService.selectDictData("mem_recharge_package_unit", String.valueOf(t.getEffectiveUnit())));
        });
        model.addAttribute("rechargePackageList", rechargePackageVOList);

        //所有行业
        List<Industry> industryList = iIndustryService.list();
        model.addAttribute("industryList", industryList);

        //获取国家列表
        LambdaQueryWrapper<Region> regionLqw = new LambdaQueryWrapper<>();
        regionLqw.eq(Region::getLevel, 1).orderByAsc(Region::getId);
        List<Region> countryList = iRegionService.list(regionLqw);
        model.addAttribute("countryList", countryList);

        //潜水等级
        List<SysDictData> diveLevelList = iSysDictTypeService.selectDictDataByType("mem_member_dan_level");
        model.addAttribute("diveLevelList", diveLevelList);

        //潜水系统
        List<SysDictData> diveSystemList = iSysDictTypeService.selectDictDataByType("mem_member_dive_system");
        model.addAttribute("diveSystemList", diveSystemList);

        return getLocaleHtml("user.html", request);
    }

    @ResponseBody
    @PostMapping("/user/exchange")
    public AjaxResult exchange(String cardNum, HttpServletRequest request){

        if(StrUtil.isBlank(cardNum)){
            throw new CustomException(400,"缺少卡券号码");
        }

        Member member = (Member)request.getAttribute("member");
        iOrderService.exchangeMemberCard(cardNum, member.getId());

        return AjaxResult.success();
    }

    @ResponseBody
    @PostMapping("/user/edit")
    public AjaxResult edit(Member member,String[] memImages, String[] certImages){
        if(StrUtil.isNotEmpty(member.getMobile2()) && !Validator.isMobile(member.getMobile2())){
            throw new CustomException(400,"请输入正确的手机号码");
        }
        if(StrUtil.isNotEmpty(member.getEmail()) && !Validator.isEmail(member.getEmail())){
            throw new CustomException(400,"请输入正确的邮箱");
        }
        member.setUpdateBy("用户");
        iMemberService.edit(member, memImages, certImages);

        return AjaxResult.success();
    }
}
